home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Net / Utilities / Seer family 2.0 / seer_common / sc_pdl_print_data.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-08-29  |  10.5 KB  |  403 lines  |  [TEXT/KAHL]

  1. /*
  2.     sp_pdl_print.c - print a data packet by interpreting the pdl data
  3.     structure
  4. */
  5.  
  6. #include "sc.h"
  7. #include "sc_seer_globals.h"
  8. #include "pdl_data.h"
  9.  
  10. #include "OUT.h"            /* how this to actually print strings */
  11.  
  12. /* forward prototype for pdl central processor unit */
  13. void pr_cpu(void);
  14.  
  15. static char maptoprint[17]="0123456789abcdef";
  16. /*
  17.     logical and mask for bit sizes
  18. */
  19. static uint32 bit_mask[33]={
  20.    0,
  21.    0x00000001,0x00000003,0x00000007,0x0000000f,
  22.    0x0000001f,0x0000003f,0x0000007f,0x000000ff,
  23.    0x000001ff,0x000003ff,0x000007ff,0x00000fff,
  24.    0x00001fff,0x00003fff,0x00007fff,0x0000ffff,
  25.    0x0001ffff,0x0003ffff,0x0007ffff,0x000fffff,
  26.    0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
  27.    0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,
  28.    0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff
  29. };
  30.  
  31. /*
  32.     pr_error - process a pdl error
  33. */
  34. void pr_error(err)
  35. char *err;
  36. {OUT_brk();
  37.  OUT_str(err);        /* print the error message */
  38.  longjmp(ppg.pr_jmp_buf,1); /* quit pdl */
  39. }
  40.  
  41. /*
  42.     load some bits from the data stream
  43. */
  44. uint32 slurp_bits(int);
  45. uint32 slurp_bits(bitsize)
  46. register int bitsize;
  47. {register uint32 result;
  48.  register int bits_here;
  49.  result=0;                    /* start with no bits on in the result */
  50.  ppg.pr_size -= bitsize;        /* account for bits used from the packet */
  51.  if(ppg.pr_size<0)
  52.   pr_error("??packet too short");
  53.  while(bitsize>0) {            /* slurp some bits */
  54.     bits_here=min(bitsize,ppg.pr_curb); /* how many to get from current byte */
  55.     bitsize -= bits_here;    /* account for the bits we are providing */
  56.     result <<= bits_here;    /* make room for this chunk */
  57.       /* bits from current byte*/
  58.     result |= (bit_mask[bits_here] & ((*ppg.pr_data)>>(ppg.pr_curb-bits_here)));
  59.  
  60.     /* advance data stream */
  61.     ppg.pr_curb -= bits_here;    /* get bits out of the current byte */
  62.     if(ppg.pr_curb==0) {        /* this byte empty? */
  63.         ppg.pr_data++;            /* advance data pointer */
  64.         ppg.pr_curb=BITS_PER_DATA; /* reset bits left in this byte */
  65.          }
  66.      }
  67.  return result;
  68. }
  69.  
  70. /*
  71.     print a number in some base
  72. */
  73. #define MAX_int_DEC (40)    /* larger than largest integer as a string */
  74. char *pr_base(char *,uint32,int);
  75. char *pr_base(dec_put,val,base)
  76. register char *dec_put;
  77. register uint32 val;
  78. register int base;
  79. {register uint32 new_val;
  80.  *--dec_put = 0;            /* end the string with a null */
  81.  do {
  82.     new_val = val / base;    /* pick out a digit */
  83.      *--dec_put = maptoprint[val - (new_val * base)];
  84.     val = new_val;            /* remaining bits */
  85.  } while (val!=0);
  86.  return dec_put;
  87. };
  88. /*
  89.     print a hex number
  90. */
  91. pr_hex(uint32);
  92. pr_hex(val)
  93. uint32 val;
  94. {char prstr[MAX_int_DEC+1];
  95.  register char *astext;
  96.  astext=pr_base(&prstr[MAX_int_DEC+1],val,16);
  97.  *--astext = '$';            /* hex numbers begin with dollar signs */
  98.  OUT_str(astext);
  99. }
  100.  
  101. /*
  102.     print a decicmal number
  103. */
  104. pr_dec(uint32);
  105. pr_dec(val)
  106. uint32 val;
  107. {char prstr[MAX_int_DEC+1];
  108.  OUT_str(pr_base(&prstr[MAX_int_DEC+1],val,10));
  109. }
  110.  
  111. /*
  112.     print a string with a count
  113. */
  114. #define out_ch(xxx) *outpt++ = (xxx)
  115. #define out_ctl(xxx) {out_ch('^');out_ch(xxx);}
  116. pr_cnt_str(void);
  117. pr_cnt_str()
  118. {register int len;
  119.  char buf[540];                /* worst case string size is 2*(2^8)+1 */
  120.  register char *outpt;        /* current pointer into the output buffer */    
  121.  register char ch;
  122.  len=slurp_bits(8);            /* get the string length */
  123.  OUT_str("[");
  124.  pr_dec(len);
  125.  OUT_str("]");
  126.  /* make up the string to print */
  127.  outpt=buf;                    /* put characters here */
  128.  out_ch('"');
  129.  while((--len)>=0) {        /* until the string is printed */
  130.     ch=slurp_bits(8);        /* get the next character from the input stream */
  131.     ch &= 0x7f;                /* mask out parity */
  132.      if(ch==0x7f)            /* a delete? */
  133.       out_ctl('?')            /* yes print this way */
  134.     else if(ch<' ')            /* less than a space, a control char? */
  135.       out_ctl(((ch&0x1f)+'@')) /* yes, print as ^x */
  136.     else if(ch=='^')        /* an up arrow? */
  137.       out_ctl('^')            /* yes, double it */
  138.     else
  139.       out_ch(ch);
  140.     }
  141.  out_ch('"');
  142.  out_ch(0);                    /* terminate the string */
  143.  OUT_str(buf);
  144. }
  145.  
  146. void pr_ip_adr(uint32);
  147. void pr_ip_adr(a_val)
  148. uint32 a_val;
  149. {pr_dec((a_val>>24) & 0xff); /* print a byte */
  150.  OUT_str(".");
  151.  pr_dec((a_val>>16) & 0xff); /* print a byte */
  152.  OUT_str(".");
  153.  pr_dec((a_val>>8) & 0xff); /* print a byte */
  154.  OUT_str(".");
  155.  pr_dec(a_val & 0xff);     /* print a byte */
  156. }
  157.  
  158. /*
  159.     impliment the field opcode
  160. */
  161. void pr_FLD(void);
  162. void pr_FLD()
  163. {register int prf_size,temp;        /* will contain size in bits of this field*/
  164.  nd_fvalue fld_vals;
  165.  register uint32 pr_value;    /* the value of this field (if a number) */
  166.  int print_how;
  167.  fld_vals = *((nd_fvalue *)&ppg.pr_ip->nd_value); /* get our bits from nd_size */
  168.  
  169.  /* figure the field size */
  170.  prf_size=fld_vals.nd_size;        /* assume the size is a number */
  171.  if(fld_vals.nd_indsize)        /* size indirect? */
  172.    prf_size=ppg.pr_regs[prf_size];    /* yes, load it from a register */
  173.  
  174.  if((temp=fld_vals.nd_indreg)!=0) {    /* load value from a register? */
  175.     pr_value=ppg.pr_regs[temp];            /* yes */
  176.      pr_value &=bit_mask[prf_size];    /* keep only bits valid for this size */
  177.     }
  178.  else
  179.      pr_value=slurp_bits(prf_size); /* get the bits from the data stream */
  180.  
  181.  
  182.  /* we have the value now, if we want to save it in a register do so */
  183.  if((temp=fld_vals.nd_lodreg)!=0) /* want to save the value? */
  184.    ppg.pr_regs[temp]=pr_value; /* yes, do so */
  185.  
  186.  
  187.  ppg.pr_last_value = pr_value;    /* save for 'name' to match */
  188.  
  189.  print_how=fld_vals.nd_print;    /* see how to print */
  190.  if(print_how==PR_REAL(NOPRINT)) /* want to print at all? */
  191.   return;                        /* no, we are done then */
  192.  
  193.  OUT_brk();                        /* break output here */
  194.  OUT_str(RES_str(ppg.pr_ip->nd_str));     /* say what the field is */
  195.  OUT_str("=");
  196.  
  197.  /* print this field as desired */
  198.  switch(print_how) {
  199.   case PR_REAL(HEX):
  200.       pr_hex(pr_value);
  201.       break;
  202.   case PR_REAL(DEC):
  203.     pr_dec(pr_value);
  204.     break;
  205.   case PR_REAL(NOPRINT):
  206.       break;
  207.   case PR_REAL(CNT_STR):
  208.     pr_cnt_str();
  209.       break;
  210.   case PR_REAL(IP_ADR):
  211.       pr_ip_adr(pr_value);
  212.       break;
  213.  }
  214. }
  215.  
  216. /*
  217.     implement the name opcode
  218. */
  219. void pr_NAME(void);
  220. void pr_NAME()
  221. {if(ppg.pr_ip->nd_value!=ppg.pr_last_value) /* match last field value? */
  222.     return;                    /*no, we have nothing to do then */
  223.  /* our value matched the last 'field' value so print our name */
  224.  OUT_str("(");
  225.  OUT_str(RES_str(ppg.pr_ip->nd_str));
  226.  OUT_str(")");
  227. }
  228.  
  229. /*
  230.     the GOSUB opcode
  231. */
  232. void pr_GOSUB(void);
  233. void pr_GOSUB()
  234. {register nd_res * save_next;
  235.  save_next = ppg.pr_next;        /* remember where to return to */
  236.  ppg.pr_ip = RES_cod(ppg.pr_ip->nd_down); /* jump to gosub destination */
  237.  pr_cpu();                    /* run the cpu for the subroutine */
  238.  ppg.pr_next = save_next;        /* go back to where we where */
  239. }
  240.  
  241. /*
  242.     the INDGSUB opcode
  243. */
  244. void pr_INDGSUB(void);
  245. void pr_INDGSUB()
  246. {register nd_res *save_next,*whereto;
  247.  save_next = ppg.pr_next;        /* remember where to return to */
  248.  whereto=(nd_res *)(ppg.pr_regs[ppg.pr_ip->nd_genreg]); /* see where to go to */
  249.  if(whereto==0)                /* no place to go if register is zero */
  250.      return;
  251.  ppg.pr_ip = whereto;            /* jump to gosub destination */
  252.  pr_cpu();                    /* run the cpu for the subroutine */
  253.  ppg.pr_next = save_next;        /* go back to where we where */
  254. }
  255.  
  256. /*
  257.     the pr_ZERO opcode
  258. */
  259. void pr_ZERO(void);
  260. void pr_ZERO()
  261. {ppg.pr_regs[ppg.pr_ip->nd_genreg]=0; /* zero a register */
  262. }
  263.  
  264. /*
  265.     pr_LOOPE - repeat till end of packet opcode
  266. */
  267. void pr_LOOPE(void);
  268. void pr_LOOPE()
  269. {register nd_res * save_pc,*to_pc;
  270.  save_pc = ppg.pr_ip;        /* remember where to return to */
  271.  to_pc=RES_cod(save_pc->nd_down); /* pc to execute*/
  272.  while(ppg.pr_size>0) {
  273.    ppg.pr_ip = to_pc;     /* jump to gosub destination */
  274.    pr_cpu();            /* run the cpu for the subroutine */
  275.    }
  276.  ppg.pr_next = save_pc +1;    /* continue on after the gosub */
  277. }
  278.  
  279. /*
  280.     pr_LOOPC - repeat for a count opcode
  281. */
  282. void pr_LOOPC(void);
  283. void pr_LOOPC()
  284. {nd_res * save_pc,*to_pc;
  285.  long count;
  286.  count=ppg.pr_regs[ppg.pr_ip->nd_genreg];    /* get the repeat count */
  287.  
  288.  save_pc = ppg.pr_ip;            /* remember where to return to */
  289.  to_pc=RES_cod(save_pc->nd_down); /* pc to execute*/
  290.  while((--count) >= 0) {    /* loop the specified number of times */
  291.    ppg.pr_ip = to_pc;         /* jump to gosub destination */
  292.    pr_cpu();                /* run the cpu for the subroutine */
  293.    }
  294.  ppg.pr_next = save_pc +1;    /* continue on after the gosub */
  295. }
  296.  
  297. /*
  298.     the protocol opcode
  299. */
  300. void pr_PROTO(void);
  301. void pr_PROTO()
  302. {if(ppg.pr_ip->nd_value!=ppg.pr_last_value) /* match last field value? */
  303.     return;                    /*no, we have nothing to do then */
  304.  /* our value matched the last 'field' value so print our name */
  305.  OUT_str("(");
  306.  OUT_str(RES_str(ppg.pr_ip->nd_str));
  307.  OUT_str(")");
  308.  
  309.  /* remember the address of our protocol handler for later */
  310.  ppg.pr_regs[ppg.pr_ip->nd_genreg]=(uint32)RES_cod(ppg.pr_ip->nd_down);
  311. }
  312.  
  313. /*
  314.      the special opcode, call a user routine
  315. */
  316. void pr_SPECIAL(void);
  317. void pr_SPECIAL()
  318. {do_special(&ppg,ppg.pr_ip->nd_value);
  319. }
  320.  
  321. /*
  322.     pdl central processing unit.
  323.     fetch an opcode, decode and execute it.
  324. */
  325. void pr_cpu()
  326. {register int opcode;        /* pr opcode for current instruction */
  327.  
  328.  while(TRUE) {
  329.    ppg.pr_next = ppg.pr_ip + 1;        /* set new instruction counter */
  330.    opcode=ppg.pr_ip->nd_type;    /* get the instruction to execute */
  331.    switch(opcode) {
  332.      case IS_FLD:
  333.          pr_FLD();            /* parse a field */
  334.          break;
  335.      case IS_END:            /* end of the instruction list */
  336.          return;
  337.          break;
  338.      case IS_NAME:            /* match a name */
  339.          pr_NAME();
  340.          break;
  341.      case IS_ZERO:
  342.          pr_ZERO();
  343.          break;
  344.      case IS_INDGSUB:
  345.          pr_INDGSUB();
  346.          break;
  347.       case IS_GOSUB:
  348.         pr_GOSUB();
  349.          break;
  350.      case IS_LOOPE:
  351.          pr_LOOPE();
  352.          break;
  353.      case IS_LOOPC:
  354.          pr_LOOPC();
  355.          break;
  356.      case IS_PROTO:
  357.          pr_PROTO();
  358.          break;
  359.      case IS_EOF:
  360.          if(ppg.pr_size!=0)
  361.           pr_error("??excess data");
  362.          break;
  363.      case IS_SPECIAL:
  364.          pr_SPECIAL();
  365.          break;
  366.      } /* end switch on opcode */
  367.    ppg.pr_ip = ppg.pr_next;
  368.    } /* end while true */
  369. }
  370.  
  371. /* print the rest in hex and ascii*/
  372. void hex_rest(void);
  373. void hex_rest()
  374. {/*if have a partial byte left */
  375.  if(ppg.pr_curb!=BITS_PER_DATA) {
  376.       OUT_brk();                        /* break output here */
  377.      OUT_str("partial byte(");
  378.      pr_hex(BITS_PER_DATA-ppg.pr_curb);
  379.      OUT_str(")=");
  380.      pr_hex(slurp_bits(ppg.pr_curb));
  381.      }
  382. }
  383.  
  384.  
  385. void pdl_print(packet,pdl_start,pdl_siz)
  386. DATA_IS *packet;            /* the raw data to print */
  387. int pdl_start;                /* how to print it */
  388. uint16 pdl_siz;                /* how big the data is (in bits) */
  389. {ppg.pr_ip=RES_cod(PDL_WORLD->starts[pdl_start]); /* start reading instructions here */
  390.  ppg.pr_size=pdl_siz;            /* how many bits of data there are */
  391.  ppg.pr_size *= 8;
  392.  ppg.pr_data=packet;            /* where to read data from */
  393.  ppg.pr_curb=BITS_PER_DATA;        /* bits left in this data byte */    
  394.  
  395.  if(setjmp(ppg.pr_jmp_buf)!=0)    /* set a place to throw errors */
  396.   return;                    /* return from an error */
  397.  
  398.  pr_cpu();                    /* run the cpu to process data */
  399.  
  400.  if(ppg.pr_size>0)            /* have left over bits at end of packet? */
  401.      hex_rest();                /* print the rest in hex and ascii*/
  402. }
  403.